import 'package:rxdart/subjects.dart';

class EventBus {
  factory EventBus() => _getInstance();
  static EventBus get instance => _getInstance();
  static EventBus _instance;
  static EventBus _getInstance() {
    if (_instance == null) {
      _instance = EventBus._internal();
    }
    return _instance;
  }

  var _map = new Map<Object, List<Subject<dynamic>>>();

  EventBus._internal() {
    // nothing
  }

  void on<T>(String eventName, void callback(T event)) {
    var list = _map.putIfAbsent(eventName, () => List<Subject<dynamic>>());
    var subject = PublishSubject<T>();
    subject.listen(callback);
    list.add(subject);
  }

  void off<T>(String eventName, [void callback(T event)]) {
    var list = _map[eventName];
    if (eventName == null || list == null) return;
    if (callback == null) {
      _map[eventName] = null;
    } else {
      list.removeWhere((subject) => subject.onListen == callback);
    }
  }

  void emit<T>(eventName, [T arg]) {
    var list = _map[eventName];
    if (list == null) return;
    int len = list.length - 1;
    //反向遍历，防止在订阅者在回调中移除自身带来的下标错位
    for (var i = len; i > -1; --i) {
      list[i].add(arg);
    }
  }
}
